<template>
  <div class="page-container">
    <el-dialog title="提示" v-model="dialogVisible" width="30%">
      <span>确认要删除该条数据吗?</span>
      <template #footer>
                <span class="dialog-footer">
                  <el-button @click="dialogVisible = false">取 消</el-button>
                  <el-button type="primary" @click="handleDelete">确 定</el-button>
                </span>
      </template>
    </el-dialog>

    <!-- 树节点操作对话框 -->
    <el-dialog
      v-model="treeDialogVisible"
      :title="isEditNode ? '编辑节点' : '添加节点'"
      width="30%"
      @close="handleTreeDialogClose"
    >
      <el-form :model="treeNodeForm" :rules="treeNodeRules" ref="treeNodeFormRef" label-width="80px" status-icon>
        <el-form-item label="节点名称" prop="name">
          <el-input v-model="treeNodeForm.name" placeholder="请输入节点名称"></el-input>
        </el-form-item>
        <el-form-item label="排序号" prop="sortNum">
          <el-input-number v-model="treeNodeForm.sortNum" :min="0" :max="9999" placeholder="请输入排序号" style="width:100%"></el-input-number>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancelTreeDialog">取 消</el-button>
          <el-button type="primary" @click="submitTreeNodeForm">确 定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 排序设置对话框 -->
    <el-dialog v-model="sortSettingVisible" title="排序设置" width="40%">
      <div v-if="sortableNodes.length > 0">
        <p class="sort-tip">方法一：拖拽节点调整顺序，点击确定保存</p>
        <p class="sort-tip">方法二：点击"当前排序号"列进行排序</p>
        <el-table
          ref="dragTable"
          :data="sortableNodes"
          style="width: 100%"
          :row-key="(row) => row.id"
          border
          :row-class-name="tableRowClassName"
          @sort-change="handleSortChange"
        >
          <el-table-column type="index" width="50" label="序号" />
          <el-table-column prop="name" label="节点名称" />
          <el-table-column prop="sortNum" label="当前排序号" width="120" sortable="custom" />
        </el-table>
      </div>
      <div v-else class="no-data">
        <p>请先选择一个有子节点的节点</p>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="sortSettingVisible = false">取 消</el-button>
          <el-button type="primary" @click="saveSortSetting">确 定</el-button>
        </span>
      </template>
    </el-dialog>

    <div class="container">
      <!-- 左侧树状结构 -->
      <div class="tree-container">
        <div class="tree-header">
          <span>查询分类</span>
          <div class="tree-tools">
            <el-button type="primary" size="small" @click="addRootNode">新增根节点</el-button>
          </div>
        </div>
        <div class="tree-filter">
          <el-input
            v-model="treeFilterText"
            placeholder="输入关键字过滤"
            clearable
            prefix-icon="Search"
          />
        </div>
        <el-tree
          ref="templateTree"
          :data="treeData"
          :props="treeProps"
          :filter-node-method="filterNode"
          highlight-current
          node-key="id"
          @node-click="handleNodeClick"
          draggable
          @node-drop="handleNodeDrop"
          class="custom-tree"
        >
          <template #default="{ node, data }">
            <div class="tree-node">
              <span class="node-label">{{ node.label }}</span>
              <div class="node-actions" v-if="data.id !== null">
                <el-tooltip content="添加子节点" placement="top" :hide-after="0">
                  <el-button size="small" text type="primary" :icon="Plus" @click.stop="addChildNode(data)" />
                </el-tooltip>
                <el-tooltip content="编辑节点" placement="top" :hide-after="0">
                  <el-button size="small" text type="primary" :icon="Edit" @click.stop="editNode(data)" />
                </el-tooltip>
                <el-tooltip content="上移" placement="top" :hide-after="0">
                  <el-button size="small" text type="primary" :icon="ArrowUp" @click.stop="moveNodeUp(data)" />
                </el-tooltip>
                <el-tooltip content="下移" placement="top" :hide-after="0">
                  <el-button size="small" text type="primary" :icon="ArrowDown" @click.stop="moveNodeDown(data)" />
                </el-tooltip>
                <el-tooltip content="删除节点" placement="top" :hide-after="0">
                  <el-button
                    size="small"
                    text
                    type="danger"
                    :icon="Delete"
                    @click.stop="removeNode(node, data)"
                    :disabled="hasChildren(data)"
                  />
                </el-tooltip>
              </div>
            </div>
          </template>
        </el-tree>
      </div>

      <!-- 右侧内容区 -->
      <div class="content-container">
        <div class="search">
          <el-form label-width="80px" :model="searchObject" ref="searchForm">
            <el-row>
              <el-col :span="6" style="padding: 0 8px;">
                <el-form-item label="查询方法" prop="id">
                  <el-input v-model="searchObject.id"  placeholder="查询方法" name="id"  @keyup.enter="search">
                  </el-input>
                </el-form-item>
              </el-col>
              <el-col :span="6" style="padding: 0 8px;">
                <el-form-item label="模板名称" prop="name">
                  <el-input v-model="searchObject.name"  placeholder="模板名称" name="name" @keyup.enter="search">
                  </el-input>
                </el-form-item>
              </el-col>

              <el-col :span="12" style="padding: 0 10px;">
                <el-row type="flex" justify="end">
                  <el-button type="primary" @click="search">搜索</el-button>
                  <el-button plain @click="clearSearch">清除条件</el-button>
                </el-row>
              </el-col>
            </el-row>
          </el-form>
        </div>
        <div class="data-content">
          <div class="tool-add">
            <el-button type="primary" @click="addView">新增</el-button>
          </div>

          <el-table v-loading="loading" :data="pageData.data" @sort-change="changeTableSort"
                    style="width: 100%;font-size: 12px;">
            <el-table-column label="模板代码" prop="id"
                          width="260">
            </el-table-column>
            <el-table-column label="模板名称" prop="name"
                          width="400">
            </el-table-column>
            <el-table-column label="模板类型" prop="type"
                          width="100">
            </el-table-column>
            <el-table-column label="模板描述" prop="note"
            >
            </el-table-column>
            <el-table-column label="添加时间" prop="addDate"    width="160" sortable="custom" >
            </el-table-column>
            <el-table-column width="210" align="center" fixed="right" label="操作">
              <template #default="scope">
                <el-button text class="operation_bt" :icon="InfoFilled" type="info" @click="showView(scope.row)">详情
                </el-button>

                <el-button text class="operation_bt" :icon="Edit" type="primary" @click="editView(scope.row)">编辑
                </el-button>

                <el-button text :icon="Delete" class="operation_bt" type="danger" style="cursor: pointer;"
                          @click="deleteData(scope.row)">删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>

          <div class="page">
            <el-pagination background :current-page="searchObject.no" :page-sizes="[10, 20, 30,50, 100]"
                          :page-size="pageData.size" :pager-count="5"
                          layout="total, sizes, prev, pager, next, jumper" :page-count="pageData.totalPage"
                          :total="pageData.total" @size-change="sizeChange" @current-change="pageChange">
            </el-pagination>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import {Delete, Edit, InfoFilled, Plus, Search, ArrowUp, ArrowDown} from '@element-plus/icons-vue'
import {defineStore} from 'pinia'
import {usePage} from "@/utils/usePage";
import {useDelete} from "@/utils/useDelete";
import {useView} from "@/utils/useView";
import {ref, reactive, watch, nextTick, getCurrentInstance, onMounted} from "vue";
import { ElMessage, ElMessageBox } from 'element-plus'
import http from "@/utils/request";
import Sortable from 'sortablejs';
import {usePageData} from "@/uses/usePageData.js";

const { proxy } = getCurrentInstance();

const searchForm = ref()
const searchStore = defineStore('queryTemplateStore', {

  state: () => {
    return {
      searchObject: {
        no: 1,
        size: 30,
        sortField: "addDate",
        sortMethod: "desc",
        name: null,
        id:null,
        queryCatalog: null,
        type: null,
        categoryId: null // 新增分类ID筛选
      }
    }
  }
})

const {searchObject} = searchStore();

const clearSearch = () => {
  searchObject.id=null;
  searchObject.name=null;
  searchObject.catalog=null;

}

const {
  pageData,
  sizeChange,
  pageChange,
  search,
  changeTableSort,
  loading
} = usePageData("query_template_list", searchObject);
const {dialogVisible, deleteData, handleDelete} = useDelete("/queryTemplate/delete", search);
const {showView, addView, editView} = useView();

// 树状结构相关数据和方法
const templateTree = ref(null);
const treeData = ref([]);
const treeProps = {
  children: 'children',
  label: 'name'
};
const treeFilterText = ref('');
const treeDialogVisible = ref(false);
const isEditNode = ref(false);
const currentNode = ref(null);
const selectedParentNode = ref(null);
const treeNodeForm = ref({
  id: null,
  name: '',
  code: '',
  parentId: null,
  parent: null,
  sortNum: 0
});
const treeNodeRules = {
  name: [
    { required: true, message: '请输入节点名称', trigger: 'blur' },
  ],
  code: [
    { required: true, message: '请输入节点代码', trigger: 'blur' },
  ],
  sortNum: [
    { required: true, message: '请输入排序号', trigger: 'blur' },
  ],
};
const treeNodeFormRef = ref(null);

// 排序设置相关
const sortSettingVisible = ref(false);
const sortableNodes = ref([]);
const dragTable = ref(null);
let sortable = null;

// 监听过滤文本变化
watch(treeFilterText, (val) => {
  templateTree.value?.filter(val);
});

// 节点过滤方法
const filterNode = (value, data) => {
  if (!value) return true;
  return data.name.toLowerCase().includes(value.toLowerCase());
};

// 获取树数据
const getTreeData = async () => {
  try {
    // 使用项目现有的http请求方式
    let res = await http.post('/queryCatalog/list', {
      fetch: 1,
      depth: 1,
      sortField: "sortNum",
      sortMethod: "asc"
    });
    if (res.code === 200) {
      // 添加"全部"节点作为第一个节点
      treeData.value = [{
        id: null,
        name: '全部',
        children: []
      }, ...(res.data || [])];
    } else {
      ElMessage.error(res.msg || '获取分类数据失败');
    }
  } catch (error) {
    console.error('获取树数据失败:', error);
    ElMessage.error('获取分类数据失败');
  }
};

// 初始化获取树数据
onMounted(() => {
  getTreeData();
});

// 添加根节点
const addRootNode = () => {
  isEditNode.value = false;
  // 重置表单数据
  treeNodeForm.id = null;
  treeNodeForm.name = '';
  treeNodeForm.code = '';
  treeNodeForm.parent = null;
  treeNodeForm.sortNum = 0;
  // 清除当前节点引用
  currentNode.value = null;
  treeDialogVisible.value = true;
};

// 添加子节点
const addChildNode = (data) => {
  isEditNode.value = false;
  // 深拷贝父节点数据，避免直接引用
  // 重置表单数据
  treeNodeForm.value.id = null;
  treeNodeForm.value.name = '';
  treeNodeForm.value.code = '';
  treeNodeForm.value.parent = data.id;
  treeNodeForm.value.sortNum = 0;
  // 保存父节点引用
  currentNode.value = data;
  treeDialogVisible.value = true;
  // 下一帧重置表单验证
};

// 辅助函数：根据ID查找节点
const findNodeById = (nodes, id) => {
  if (!nodes || nodes.length === 0) return null;

  for (const node of nodes) {
    if (node.id === id) return node;

    if (node.children && node.children.length > 0) {
      const found = findNodeById(node.children, id);
      if (found) return found;
    }
  }

  return null;
};

// 辅助函数：根据ID查找节点及其父节点
const findNodeAndParentById = (nodes, id, parent = null) => {
  if (!nodes || nodes.length === 0) return null;

  for (const node of nodes) {
    if (node.id === id) {
      return { node, parent };
    }

    if (node.children && node.children.length > 0) {
      const result = findNodeAndParentById(node.children, id, node);
      if (result) return result;
    }
  }

  return null;
};

// 通过ID更新树节点属性的方法
const updateTreeNodeById = (id, properties) => {
  const node = findNodeById(treeData.value, id);
  if (node) {
    Object.assign(node, properties);
    return true;
  }
  return false;
};

// 通过ID在树中查找并删除节点
const removeTreeNodeById = (id) => {
  const result = findNodeAndParentById(treeData.value, id);
  if (!result) return false;

  const { node, parent } = result;

  // 如果是根节点
  if (!parent) {
    const index = treeData.value.findIndex(item => item.id === id);
    if (index !== -1) {
      treeData.value.splice(index, 1);
      return true;
    }
  }
  // 如果是子节点
  else if (parent.children) {
    const index = parent.children.findIndex(item => item.id === id);
    if (index !== -1) {
      parent.children.splice(index, 1);
      return true;
    }
  }

  return false;
};

// 编辑节点
const editNode = (data) => {
  isEditNode.value = true;
  // 深拷贝节点数据，避免直接引用可能导致的问题
  const nodeData = JSON.parse(JSON.stringify(data));
  console.info('编辑节点:', nodeData.name)

  treeNodeForm.value.id = nodeData.id;
  treeNodeForm.value.name = nodeData.name;
  treeNodeForm.value.code = nodeData.code;
  treeNodeForm.value.sortNum = nodeData.sortNum || 0;

  console.info('编辑节点:',  treeNodeForm.value.name)

  // 保存当前编辑的节点数据
  currentNode.value = data;
  treeDialogVisible.value = true;
  // 下一帧重置表单验证
};

// 保存节点
const submitTreeNodeForm = async () => {
  await treeNodeFormRef.value.validate(async (valid) => {
    if (valid) {
      try {
        const url = isEditNode.value
          ? '/queryCatalog/update'
          : '/queryCatalog/create';

        // 创建一个新对象来发送，避免引用问题
        const formData = { ...treeNodeForm.value };

        // 使用项目现有的http请求方式
        let res = await http.post(url, formData);

        if (res.code === 200) {
          ElMessage.success(isEditNode.value ? '更新成功' : '添加成功');
          treeDialogVisible.value = false;

          // 添加日志用于调试
          console.log('服务器返回数据:', res.data);
          console.log('当前节点:', currentNode.value);
          console.log('更新URL:', url);

          // 清空表单数据，避免数据残留
          treeNodeForm.id = null;
          treeNodeForm.name = '';
          treeNodeForm.code = '';
          treeNodeForm.parentId = null;
          treeNodeForm.parent = null;
          treeNodeForm.sortNum = 0;

          if (currentNode.value){
            if (!currentNode.value.children){
              currentNode.value.children = [];
            }

            if("/queryCatalog/update" === url){
              // 更新节点属性
                const node = findNodeById(treeData.value, formData.id);
                console.info("node",node)
                if (node) {
                  node.name= formData.name;
                }
            } else {
              currentNode.value.children.push(res.data);
            }
          }else{
            await getTreeData();
          }
          currentNode.value = null;
          //await getTreeData();
        } else {
          ElMessage.error(res.msg || (isEditNode.value ? '更新失败' : '添加失败'));
        }
      } catch (error) {
        console.error('保存节点失败:', error);
        ElMessage.error(isEditNode.value ? '更新失败' : '添加失败');
      }
    }
  });
};

// 删除节点
const removeNode = (node, data) => {
  ElMessageBox.confirm(`确定要删除 ${data.name} 吗?`, '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    try {
      // 使用项目现有的http请求方式
      let res = await http.post(`/queryCatalog/delete`, { id: data.id });

      if (res.code === 200) {
        ElMessage.success('删除成功');

        // 从树中移除节点
        removeTreeNodeById(data.id);

        // 如果删除的是当前选中的节点，清除搜索条件
        if (selectedParentNode.value && selectedParentNode.value.id === data.id) {
          selectedParentNode.value = null;
          searchObject.categoryId = null;
          search();
        }
      } else {
        ElMessage.error(res.msg || '删除失败');
      }
    } catch (error) {
      console.error('删除节点失败:', error);
      ElMessage.error('删除失败');
    }
  }).catch(() => {});
};

// 检查节点是否有子节点
const hasChildren = (data) => {
  return data.children && data.children.length > 0;
};

// 处理节点点击
const handleNodeClick = (data) => {
  // 记录选中的节点用于排序
  selectedParentNode.value = data;

  // 更新搜索条件，根据选中的分类节点筛选数据
  searchObject.catalog = data.id; // 当点击"全部"节点时，catalog将为null
  searchObject.no = 1;
  search();
};

// 处理节点拖拽
const handleNodeDrop = async (draggingNode, dropNode, dropType, ev) => {
  try {
    // 根据拖拽类型更新节点的父级和顺序
    const dragData = {
      id: draggingNode.data.id,
      targetId: dropNode.data.id,
      dropType: dropType
    };

    // 使用项目现有的http请求方式
    let res = await http.post('/queryCatalog/move', dragData);

    if (res.code === 200) {
      ElMessage.success('移动成功');
      await getTreeData();
    } else {
      ElMessage.error(res.msg || '移动失败');
      await getTreeData(); // 失败时重新加载，恢复原状态
    }
  } catch (error) {
    console.error('节点移动失败:', error);
    ElMessage.error('移动失败');
    await getTreeData(); // 失败时重新加载，恢复原状态
  }
};

// 上移节点
const moveNodeUp = async (data) => {
  try {
    // 找到同级节点列表
    let siblingNodes = [];
    if (data.parent) {
      // 如果有父节点，找到父节点下的所有子节点
      const parentNode = findNodeById(treeData.value, data.parent);
      if (parentNode && parentNode.children) {
        siblingNodes = parentNode.children;
      }
    } else {
      // 如果是根节点，获取所有根节点
      siblingNodes = treeData.value;
    }

    // 先确保所有节点都有唯一的排序号（处理sortNum相同或为0的情况）
    const normalizedNodes = normalizeSortNumbers(siblingNodes);

    // 找到当前节点的索引
    const currentIndex = normalizedNodes.findIndex(node => node.id === data.id);
    if (currentIndex <= 0) {
      ElMessage.warning('已经是第一个节点，无法上移');
      return;
    }

    // 获取上一个节点
    const prevNode = normalizedNodes[currentIndex - 1];

    // 交换排序号
    const currentSortNum = normalizedNodes[currentIndex].sortNum;
    const prevSortNum = prevNode.sortNum;

    // 先更新当前节点
    let updateCurrent = await http.post('/queryCatalog/update', {
      id: data.id,
      sortNum: prevSortNum,
      name: data.name,
      code: data.code
    });

    if (updateCurrent.code !== 200) {
      ElMessage.error(updateCurrent.msg || '上移失败');
      return;
    }

    // 再更新前一个节点
    let updatePrev = await http.post('/queryCatalog/update', {
      id: prevNode.id,
      sortNum: currentSortNum,
      name: prevNode.name,
      code: prevNode.code
    });

    if (updatePrev.code === 200) {
      ElMessage.success('上移成功');
      await getTreeData(); // 刷新树数据
    } else {
      ElMessage.error(updatePrev.msg || '上移失败');
      // 如果第二次更新失败，需要将第一个节点还原
      await http.post('/queryCatalog/update', {
        id: data.id,
        sortNum: currentSortNum,
        name: data.name,
        code: data.code
      });
    }
  } catch (error) {
    console.error('节点上移失败:', error);
    ElMessage.error('上移失败');
  }
};

// 下移节点
const moveNodeDown = async (data) => {
  try {
    // 找到同级节点列表
    let siblingNodes = [];
    if (data.parent) {
      // 如果有父节点，找到父节点下的所有子节点
      const parentNode = findNodeById(treeData.value, data.parent);
      if (parentNode && parentNode.children) {
        siblingNodes = parentNode.children;
      }
    } else {
      // 如果是根节点，获取所有根节点
      siblingNodes = treeData.value;
    }

    // 先确保所有节点都有唯一的排序号（处理sortNum相同或为0的情况）
    const normalizedNodes = normalizeSortNumbers(siblingNodes);

    // 找到当前节点的索引
    const currentIndex = normalizedNodes.findIndex(node => node.id === data.id);
    if (currentIndex === -1 || currentIndex >= normalizedNodes.length - 1) {
      ElMessage.warning('已经是最后一个节点，无法下移');
      return;
    }

    // 获取下一个节点
    const nextNode = normalizedNodes[currentIndex + 1];

    // 交换排序号
    const currentSortNum = normalizedNodes[currentIndex].sortNum;
    const nextSortNum = nextNode.sortNum;

    // 先更新当前节点
    let updateCurrent = await http.post('/queryCatalog/update', {
      id: data.id,
      sortNum: nextSortNum,
      name: data.name,
      code: data.code
    });

    if (updateCurrent.code !== 200) {
      ElMessage.error(updateCurrent.msg || '下移失败');
      return;
    }

    // 再更新下一个节点
    let updateNext = await http.post('/queryCatalog/update', {
      id: nextNode.id,
      sortNum: currentSortNum,
      name: nextNode.name,
      code: nextNode.code
    });

    if (updateNext.code === 200) {
      ElMessage.success('下移成功');
      await getTreeData(); // 刷新树数据
    } else {
      ElMessage.error(updateNext.msg || '下移失败');
      // 如果第二次更新失败，需要将第一个节点还原
      await http.post('/queryCatalog/update', {
        id: data.id,
        sortNum: currentSortNum,
        name: data.name,
        code: data.code
      });
    }
  } catch (error) {
    console.error('节点下移失败:', error);
    ElMessage.error('下移失败');
  }
};

// 为节点分配唯一的排序号
const normalizeSortNumbers = (nodes) => {
  if (!nodes || nodes.length === 0) return [];

  // 先对节点按现有排序号排序（如果排序号相同或为0，则按照它们在数组中的顺序）
  const sortedNodes = [...nodes];
  sortedNodes.sort((a, b) => {
    // 如果a和b的sortNum都存在且不相等，则按sortNum排序
    if (a.sortNum && b.sortNum && a.sortNum !== b.sortNum) {
      return a.sortNum - b.sortNum;
    }
    // 否则保持原有顺序
    return 0;
  });

  // 为每个节点分配新的连续排序号（从1开始）
  const normalizedNodes = sortedNodes.map((node, index) => {
    return {
      ...node,
      sortNum: index + 1
    };
  });

  return normalizedNodes;
};

// 打开排序设置对话框
const openSortSetting = () => {
  // 初始化为空数组
  sortableNodes.value = [];

  if (!selectedParentNode.value) {
    // 如果没有选中节点，则排序根节点
    if (treeData.value && treeData.value.length > 0) {
      sortableNodes.value = treeData.value.slice().map((node, index) => {
        // 确保每个节点都有id字段
        return {
          ...node,
          id: node.id || `temp_id_${index}`,
          _index: index  // 添加内部索引作为备用标识
        };
      });
    }
  } else if (hasChildren(selectedParentNode.value)) {
    // 如果选中节点有子节点，则排序其子节点
    sortableNodes.value = selectedParentNode.value.children.slice().map((node, index) => {
      // 确保每个节点都有id字段
      return {
        ...node,
        id: node.id || `temp_id_${index}`,
        _index: index  // 添加内部索引作为备用标识
      };
    });
  }

  sortSettingVisible.value = true;

  // 下一帧初始化拖拽排序
  nextTick(() => {
    if (!dragTable.value || sortableNodes.value.length === 0) return;

    // 添加延迟确保DOM渲染完成
    setTimeout(() => {
      const tbody = dragTable.value?.$el.querySelector('.el-table__body-wrapper tbody');
      if (!tbody) {
        console.error('找不到表格主体元素');
        return;
      }

      if (sortable) {
        sortable.destroy();
        sortable = null;
      }

      try {
        sortable = Sortable.create(tbody, {
          handle: '.sortable-row',
          animation: 150,
          ghostClass: 'sortable-ghost',
          onEnd({ newIndex, oldIndex }) {
            if (newIndex === undefined || oldIndex === undefined || newIndex === oldIndex) return;

            // 使用Vue的数组方法确保响应式更新
            const currRow = sortableNodes.value[oldIndex];
            const newNodes = [...sortableNodes.value];
            newNodes.splice(oldIndex, 1);
            newNodes.splice(newIndex, 0, currRow);
            sortableNodes.value = newNodes;
          }
        });
      } catch (error) {
        console.error('初始化拖拽排序失败:', error);
        ElMessage.warning('初始化拖拽排序失败，请重试');
      }
    }, 100);
  });
};

// 保存排序设置
const saveSortSetting = async () => {
  try {
    if (sortableNodes.value.length === 0) {
      ElMessage.warning('没有可排序的节点');
      return;
    }

    // 检查是否有临时ID
    const hasTempId = sortableNodes.value.some(node =>
      typeof node.id === 'string' && node.id.startsWith('temp_id_')
    );

    if (hasTempId) {
      ElMessage.warning('存在临时节点ID，请先保存所有节点');
      return;
    }

    // 为每个节点重新设置排序号
    const updateData = sortableNodes.value.map((node, index) => {
      return {
        id: node.id,
        sortNum: index + 1
      };
    });

    // 使用项目现有的http请求方式
    let res = await http.post('/queryCatalog/batchUpdateSort', { nodes: updateData });

    if (res.code === 200) {
      ElMessage.success('排序更新成功');
      sortSettingVisible.value = false;
      await getTreeData();
    } else {
      ElMessage.error(res.msg || '排序更新失败');
    }
  } catch (error) {
    console.error('保存排序设置失败:', error);
    ElMessage.error('排序更新失败');
  }
};

// 为表格行提供class名称
const tableRowClassName = (row) => {
  // 确保row和row.row存在
  if (!row || !row.row) return 'sortable-row';
  return 'sortable-row';
};

// 处理表格排序变化
const handleSortChange = ({ prop, order }) => {
  if (prop === 'sortNum') {
    if (order === 'ascending') {
      sortableNodes.value.sort((a, b) => (a.sortNum || 0) - (b.sortNum || 0));
    } else if (order === 'descending') {
      sortableNodes.value.sort((a, b) => (b.sortNum || 0) - (a.sortNum || 0));
    }
  }
};

// 处理对话框关闭事件
const handleTreeDialogClose = () => {
  // 清空表单数据
  treeNodeForm.id = null;
  treeNodeForm.name = '';
  treeNodeForm.code = '';
  treeNodeForm.parentId = null;
  treeNodeForm.parent = null;
  treeNodeForm.sortNum = 0;
  currentNode.value = null;
  // 重置表单验证
  treeNodeFormRef.value?.resetFields();
};

// 添加取消按钮的处理函数（在合适的位置，如handleTreeDialogClose函数后面）
const cancelTreeDialog = () => {
  treeDialogVisible.value = false;
  // 对话框关闭事件会处理清空表单
};
</script>

<style scoped lang="scss">
.page-container {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
}

.container {
  display: flex;
  height: 100%;
  overflow: hidden; /* 防止容器出现滚动条 */
  flex: 1; /* 占满剩余空间 */
}

.tree-container {
  width: 280px;
  min-width: 200px; /* 降低最小宽度，更好地适应小屏幕 */
  max-width: 320px;
  border-right: 1px solid #ebeef5;
  padding: 0; /* 移除内边距 */
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden; /* 防止水平滚动条 */
  box-sizing: border-box; /* 确保padding不增加宽度 */
  background-color: #fff; /* 白色背景 */
}

.tree-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px; /* 调整内边距 */
  border-bottom: 1px solid #ebeef5;
  margin-bottom: 0; /* 移除底部间距 */
  min-width: 0; /* 允许子元素缩小 */
  width: 100%; /* 填充可用空间 */
  background-color: #fff; /* 白色背景 */
  box-sizing: border-box;
}

.tree-tools {
  display: flex;
  gap: 5px;
}

.tree-filter {
  margin: 12px 16px; /* 调整外边距 */
  padding: 0; /* 移除内边距 */
}

.custom-tree {
  width: 100%;
  overflow: hidden;
  background-color: #fff; /* 白色背景 */
  padding: 0 8px 8px 8px; /* 调整内边距 */
  flex: 1; /* 占满剩余空间 */
  overflow-y: auto; /* 内容过多时滚动 */
}

.tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 8px; /* 调整内边距 */
  min-width: 0; /* 允许内容在必要时缩小 */
  width: 100%; /* 确保宽度100% */
  border-radius: 4px; /* 圆角 */
  transition: background-color 0.3s ease; /* 只保留背景色过渡效果 */
  position: relative; /* 添加相对定位 */
}

.node-label {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  margin-right: 5px;
  flex: 1;
  color: #606266; /* 文字颜色 */
  font-size: 14px; /* 字体大小 */
}

.node-actions {
  display: none; /* 默认隐藏操作按钮 */
  flex-shrink: 0;
  margin-left: auto;
  flex-wrap: nowrap;
  white-space: nowrap;
  background-color: transparent; /* 移除背景色 */
  border-radius: 4px; /* 圆角 */
  padding: 2px 4px; /* 内边距 */
  position: absolute; /* 绝对定位 */
  right: 8px; /* 右侧距离 */
  top: 50%; /* 垂直居中 */
  transform: translateY(-50%); /* 垂直居中 */
}

.tree-node:hover {
  background-color: #f5f7fa; /* 悬停背景色 */
}

.tree-node:hover .node-actions {
  display: flex; /* 悬停时显示操作按钮 */
}

.content-container {
  flex: 1;
  padding: 10px;
  overflow: hidden; /* 防止容器出现滚动条 */
  min-width: 0; /* 确保内容区域可以缩小 */
  background-color: #fff; /* 内容区域背景色 */
  display: flex;
  flex-direction: column;
  height: 100%;
}

.search {
  margin-bottom: 10px;
}

.data-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden; /* 防止容器出现滚动条 */
  border: none;
}

.tool-add {
  margin-bottom: 10px;
}

.page {
  margin-top: 15px;
  display: flex;
  justify-content: center;
}

/* 排序相关样式 */
.sort-tip {
  margin-bottom: 10px;
  color: #909399;
  font-size: 14px;
}

.no-data {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 200px;
  color: #909399;
}

/* 使用深度选择器修改Element Plus表格的样式 */
:deep(.el-table) {
  --el-table-border-color: #dcdfe6;
  flex: 1; /* 表格占满剩余空间 */
  overflow: auto; /* 内容过多时滚动 */
}

:deep(.sortable-row) {
  cursor: move !important;
  transition: background-color 0.2s ease;
}

:deep(.sortable-row:hover) {
  background-color: #f5f7fa !important;
}

:deep(.el-table__body) {
  width: 100% !important;
}

:deep(.sortable-ghost) {
  background-color: #e6f1fc !important;
  opacity: 0.8 !important;
}

:deep(.el-dialog__body) {
  padding-top: 10px;
  padding-bottom: 10px;
}

/* 确保树结构相关元素不会产生滚动条 */
:deep(.el-tree-node__content) {
  height: auto;
  min-height: 30px;
  padding: 4px 0;
  overflow: hidden;
  transition: background-color 0.3s ease;
}

:deep(.el-tree-node__content:hover) {
  background-color: #f5f7fa;
}

/* 拖拽节点时的样式 */
:deep(.is-dragging) {
  background-color: #e6f1fc !important;
  color: #409eff;
  font-weight: bold;
  opacity: 0.8;
}

:deep(.is-dragging .node-label) {
  color: #409eff;
}

:deep(.is-drop-inner) {
  background-color: #f0f9eb !important;
  color: #67c23a;
  border: 1px dashed #67c23a !important;
}

:deep(.is-drop-inner>.el-tree-node__content) {
  background-color: #f0f9eb !important;
}

:deep(.el-tree__drop-indicator) {
  background-color: #409eff !important;
  height: 2px !important;
}

:deep(.el-tree-node.is-drop-inner>.el-tree-node__content .node-label) {
  color: #67c23a;
}

:deep(.el-tree) {
  width: auto !important;
  max-width: 100%;
}

:deep(.el-tree-node__children) {
  overflow: hidden;
}

:deep(.el-tree-node) {
  width: 100%;
  overflow: hidden !important;
}

/* 按钮样式优化 */
:deep(.el-button--small) {
  padding: 2px;
  margin-left: 0;
  min-width: 22px;
}

:deep(.el-tooltip__trigger) {
  margin: 0 1px;
}

:deep(.el-button.is-text) {
  padding: 2px 3px;
}

/* 响应式设计 */
@media (max-width: 320px) {
  .tree-tools {
    flex-direction: column;
    gap: 5px;
  }
}

@media (max-width: 300px) {
  .node-actions {
    position: absolute;
    right: 5px;
    background: white;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    border-radius: 4px;
    padding: 2px;
    z-index: 10;
  }

  .node-label {
    max-width: 150px;
  }
}
</style>
